
package venndiagram;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;

import java.io.PrintWriter;
import java.util.*;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CompareData {
    
    private ArrayList a;
    private ArrayList b;
    private ArrayList c;
    private ArrayList ab;
    private ArrayList bc;
    private ArrayList ac;
    private ArrayList abc;
    
    private String aName;
    private String bName;
    private String cName;
    
    // Character Markers for Gene Lists
    private final char FIRST = 'A';
    private final char SECOND = 'B';
    private final char THIRD = 'C';
    
    private HashMap<String,Gene> geneMap;
    //Nicole
    public CompareData(String aFilename, String bFilename, String aSetName, String bSetName) throws Exception{
        // initialize instance variables
        geneMap = new HashMap<String,Gene>();
        a = new ArrayList();
        b = new ArrayList();
        ab = new ArrayList();
        aName = aSetName;
        bName = bSetName;
        
        // call methods
        addSet(aFilename, FIRST);
        addSet(bFilename, SECOND);
        fillLists();
        
        
    }
    //Nicole
    public CompareData(String aFilename, String bFilename, String cFilename, String aSetName, String bSetName, String cSetName) throws Exception {
        // initialize instance variables
        geneMap = new HashMap<String,Gene>();
        a = new ArrayList();
        b = new ArrayList();
        c = new ArrayList();
        ab = new ArrayList();
        ac = new ArrayList();
        bc = new ArrayList();
        abc = new ArrayList();
        aName = aSetName;
        bName = bSetName;
        cName = cSetName;
        
        // call methods
        addSet(aFilename, FIRST);
        addSet(bFilename, SECOND);
        addSet(cFilename, THIRD);
        fillLists();
        
    }

    //Adam Dalby
    //Fill set lists with names of appropriate genes
    private void fillLists()
    {
        Collection mapValues = geneMap.values();        //Collection of all genes contained in map
        Iterator mapIterator = mapValues.iterator();    //Iterator for gene collection

        //Iterate through collection of genes, sorting them into appropriate lists
        while(mapIterator.hasNext())
        {
            Gene currentGene = (Gene) mapIterator.next();   //Current gene to be sorted

            if(currentGene.a == true)
            {
                if(currentGene.b == true)
                {
                    if(currentGene.c == true)
                        abc.add(currentGene.name);
                    else
                        ab.add(currentGene.name);
                }
                else
                {
                    if(currentGene.c == true)
                        ac.add(currentGene.name);
                    else
                        a.add(currentGene.name);
                }
            }
            else
            {
                if(currentGene.b == true)
                {
                    if(currentGene.c == true)
                        bc.add(currentGene.name);
                    else
                        b.add(currentGene.name);
                }
                else
                        c.add(currentGene.name);
            }
        }
    }
    
    //Jim Choinoski
    public void createOutputThreeLists(File saveFile, String aSetName, String bSetName, String cSetName) {
        
        //create a PrintWriter and assign it to be null
        PrintWriter outputTextFile = null;
        
        int maxListSize = 0;
        
        if (a.size() > maxListSize){
            maxListSize = a.size();
        }
        if (b.size() > maxListSize){
            maxListSize = b.size();
        }
        if (c.size() > maxListSize){
            maxListSize = c.size();
        }
        if (ab.size() > maxListSize){
            maxListSize = ab.size();
        }
        if (bc.size() > maxListSize){
            maxListSize = bc.size();
        }
        if (ac.size() > maxListSize){
            maxListSize = ac.size();
        }
        if (abc.size() > maxListSize){
            maxListSize = abc.size();
        }
        
        //this try-catch block is necessary in order to catch an IOException
        try {
            //initialize outputTextFile to be a new PrintWriter, with the output sent to "outputTextFile.txt"
            outputTextFile = new PrintWriter(new FileOutputStream(saveFile.getCanonicalFile()));  // + "outputTextFile.txt"
            
            outputTextFile.print(aSetName + " Only  \t" + bSetName + " Only  \t" + cSetName + " Only  \t" +
                                 aSetName + " and " + bSetName + "\t" + bSetName + " and " + cSetName + "\t" +
                                 aSetName + " and "  + cSetName + "\t" + aSetName + ", " + bSetName + ", and " + cSetName);
            
            String geneString = "";
            
            //while the ArrayLists still conatin information, continue this for loop
            for (int index = 0; index < maxListSize; index++){
                
                outputTextFile.print("\n");
                
                
                if (index < a.size()){
                    
                    geneString = (String)(a.get(index));
                    
                    if (a.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(a.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(a.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(a.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                
                
                if (index < b.size()){
                    
                    geneString = (String)(b.get(index));
                    
                    if (b.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(b.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(b.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(b.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                  
                
                if (index < c.size()){
                    
                    geneString = (String)(c.get(index));
                    
                    if (c.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(c.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(c.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(c.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                   
                
                
                if (index < ab.size()){
                    
                    geneString = (String)(ab.get(index));
                    
                    if (ab.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(ab.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(ab.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(ab.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                           
                
                
                if (index < bc.size()){
                    
                    geneString = (String)(bc.get(index));
                    
                    if (bc.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(bc.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(bc.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(bc.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                            
                
                if (index < ac.size()){
                    
                    geneString = (String)(ac.get(index));
                    
                    if (ac.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(ac.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(ac.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(ac.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                
                
                if (index < abc.size()){
                    
                    geneString = (String)(abc.get(index));
                    
                    if (abc.get(index) != null){
                        if ((geneString.length() > 1) && (geneString.length() < 4)){
                            outputTextFile.print(abc.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(abc.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(abc.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                } 
                

            } 
        }
        catch (IOException e) {
            System.out.println(e);
        }
        //finally, close the outputTextFile PrintWriter
        finally {
            outputTextFile.close();
        }
        
    }
    
    //Jim Choinoski
    public void createOutputTwoLists(File saveFile, String aSetName, String bSetName) {
        
        //create a PrintWriter and assign it to be null
        PrintWriter outputTextFile = null;
        
        int maxListSize = 0;
        
        if (a.size() > maxListSize){
            maxListSize = a.size();
        }
        if (b.size() > maxListSize){
            maxListSize = b.size();
        }
        if (ab.size() > maxListSize){
            maxListSize = ab.size();
        }
               
        //this try-catch block is necessary in order to catch an IOException
        try {
            //initialize outputTextFile to be a new PrintWriter, with the output sent to "outputTextFile.txt"
            outputTextFile = new PrintWriter(new FileOutputStream(saveFile.getCanonicalFile()));

            outputTextFile.print(aSetName + " Only  \t" + bSetName + " Only  \t" + aSetName + " and " + bSetName);
            
            String geneString = "";
            
            //while the ArrayLists still conatin information, continue this for loop
            for (int index = 0; index < maxListSize; index++){
                
                outputTextFile.print("\n");
                
                if (index < a.size()){
                    
                    geneString = (String)(a.get(index));
                    
                    if (a.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(a.get(index) +"       \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(a.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(a.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }
                
                
                if (index < b.size()){
                    
                    geneString = (String)(b.get(index));
                    
                    if (b.get(index) != null){
                        if (geneString.length() < 4){
                            outputTextFile.print(b.get(index) +"      \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(b.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(b.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                } 
                
                
                if (index < ab.size()){
                                       
                    geneString = (String)(ab.get(index));
                    
                    if (ab.get(index) != null) {
                        if ((geneString.length() > 1) && (geneString.length() < 4)){
                            outputTextFile.print(ab.get(index) +"      \t");
                        }
                        else if ((geneString.length() >= 4) && (geneString.length() < 8)){
                            outputTextFile.print(ab.get(index) +"    \t");
                        }
                        else if (geneString.length() >= 8){
                            outputTextFile.print(ab.get(index) +"\t");
                        }
                    }
                }
                else{
                    outputTextFile.print("        \t");
                }

                
            } 
        }
        catch (IOException e) {
            System.out.println(e);
        }
        //finally, close the outputTextFile PrintWriter
        finally {
            outputTextFile.close();
            
        }
        
    }
    
    //Adam Dalby
    //Add set of genes from file to geneMap
    public void addSet(String filename, char name)
    {
        {
            //Code to execute if file is found
            try
            {
                //Set up BufferedReader to read from file
                BufferedReader in = new BufferedReader(new FileReader(filename));

                String line = null; //Line read

                //Add first list of genes to geneMap
                if(name == FIRST)
                {
                    try
                    {
                        while ((line = in.readLine()) != null)
                        {
                            Gene entryGene = new Gene(); //Gene to be added
                            entryGene.a = true;
                            entryGene.name = line;
                            //Add gene to geneMap
                            geneMap.put(line, entryGene);
                        }
                    }
                    catch (IOException ex)
                    {
                        Logger.getLogger(CompareData.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

                //Add gene or update boolean indicator of second list of genes
                else if(name == SECOND)
                {
                        try
                        {
                            while ((line = in.readLine()) != null)
                            {
                                //Update gene if it already exists in geneMap
                                if (geneMap.containsKey(line))
                                {
                                    geneMap.get(line).b = true;
                                }

                                //Create and add gene to geneMap if it does not yet exist
                                else
                                {
                                    Gene entryGene = new Gene(); //Gene to be added
                                    entryGene.b = true;
                                    entryGene.name = line;
                                    geneMap.put(line, entryGene);
                                }
                            }
                        }
                        catch (IOException ex)
                        {
                            Logger.getLogger(CompareData.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }

                //Add gene or update boolean indicator of third list of genes
                else if(name == THIRD)
                {
                        try
                        {
                            while ((line = in.readLine()) != null)
                            {
                                //Update gene if it already exists in geneMap
                                if (geneMap.containsKey(line))
                                {
                                    geneMap.get(line).c = true;
                                }

                                //Create and add gene to geneMap if it does not yet exist
                                else
                                {
                                    Gene entryGene = new Gene(); //Gene to be added
                                    entryGene.c = true;
                                    entryGene.name = line;
                                    geneMap.put(line, entryGene);
                                }
                            }
                        }
                        catch (IOException ex)
                        {
                            Logger.getLogger(CompareData.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }

                //Remove blank line if it has been added as a key to geneMap
                if(geneMap.containsKey(""))
                    geneMap.remove("");

            }
            //File not found
            catch (FileNotFoundException ex)
            {
                Logger.getLogger(CompareData.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }
    
//    public int getSizeA() {
//        if (c == null){
//            return a.size() + ab.size();
//        } else {
//            return a.size() + ab.size() + ac.size() + abc.size();
//        }
//    }
//
//    public int getSizeB() {
//        if (c == null){
//            return b.size() + ab.size();
//        } else {
//            return b.size() + ab.size() + bc.size() + abc.size();
//        }
//    }
//
//    public int getSizeC() {
//        return c.size() + ac.size() + bc.size() + abc.size();
//    }
//
//    public int getSizeAB() {
//        if (c == null){
//            return ab.size();
//        } else {
//            return ab.size() + abc.size();
//        }
//    }
//
//    public int getSizeBC() {
//        return bc.size() + abc.size();
//    }
//
//    public int getSizeAC() {
//        return ac.size() + abc.size();
//    }
//
//    public int getSizeABC() {
//        return abc.size();
//    }

    public int getSizeA(){
        return a.size();
    }

    public int getSizeB(){
        return b.size();
    }

    public int getSizeC(){
        return c.size();
    }

    public int getSizeAB(){
        return ab.size();
    }

    public int getSizeAC(){
        return ac.size();
    }

    public int getSizeBC(){
        return bc.size();
    }

    public int getSizeABC(){
        return abc.size();
    }
    
    public ArrayList getA(){
        return a;
    }
    public ArrayList getB(){
        return b;
    }
    public ArrayList getAB(){
        return ab;
    }
    public ArrayList getC(){
        return c;
    }
    public ArrayList getAC(){
        return ac;
    }
    public ArrayList getBC(){
        return bc;
    }
    public ArrayList getABC(){
        return abc;
    }
}
